{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-title"
    ]
   },
   "source": [
    "# Softmax exercise\n",
    "\n",
    "*Complete and hand in this completed worksheet (including its outputs and any supporting code outside of the worksheet) with your assignment submission. For more details see the [assignments page](http://vision.stanford.edu/teaching/cs231n/assignments.html) on the course website.*\n",
    "\n",
    "This exercise is analogous to the SVM exercise. You will:\n",
    "\n",
    "- implement a fully-vectorized **loss function** for the Softmax classifier\n",
    "- implement the fully-vectorized expression for its **analytic gradient**\n",
    "- **check your implementation** with numerical gradient\n",
    "- use a validation set to **tune the learning rate and regularization** strength\n",
    "- **optimize** the loss function with **SGD**\n",
    "- **visualize** the final learned weights\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "tags": [
     "pdf-ignore"
    ]
   },
   "outputs": [],
   "source": [
    "import random\n",
    "import numpy as np\n",
    "from cs231n.data_utils import load_CIFAR10\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "%matplotlib inline\n",
    "plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots\n",
    "plt.rcParams['image.interpolation'] = 'nearest'\n",
    "plt.rcParams['image.cmap'] = 'gray'\n",
    "\n",
    "# for auto-reloading extenrnal modules\n",
    "# see http://stackoverflow.com/questions/1907993/autoreload-of-modules-in-ipython\n",
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": [
     "pdf-ignore"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train data shape:  (49000, 3073)\n",
      "Train labels shape:  (49000,)\n",
      "Validation data shape:  (1000, 3073)\n",
      "Validation labels shape:  (1000,)\n",
      "Test data shape:  (1000, 3073)\n",
      "Test labels shape:  (1000,)\n",
      "dev data shape:  (500, 3073)\n",
      "dev labels shape:  (500,)\n"
     ]
    }
   ],
   "source": [
    "def get_CIFAR10_data(num_training=49000, num_validation=1000, num_test=1000, num_dev=500):\n",
    "    \"\"\"\n",
    "    Load the CIFAR-10 dataset from disk and perform preprocessing to prepare\n",
    "    it for the linear classifier. These are the same steps as we used for the\n",
    "    SVM, but condensed to a single function.  \n",
    "    \"\"\"\n",
    "    # Load the raw CIFAR-10 data\n",
    "    cifar10_dir = 'cs231n/datasets/cifar-10-batches-py'\n",
    "    \n",
    "    # Cleaning up variables to prevent loading data multiple times (which may cause memory issue)\n",
    "    try:\n",
    "       del X_train, y_train\n",
    "       del X_test, y_test\n",
    "       print('Clear previously loaded data.')\n",
    "    except:\n",
    "       pass\n",
    "\n",
    "    X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)\n",
    "    \n",
    "    # subsample the data\n",
    "    mask = list(range(num_training, num_training + num_validation))\n",
    "    X_val = X_train[mask]\n",
    "    y_val = y_train[mask]\n",
    "    mask = list(range(num_training))\n",
    "    X_train = X_train[mask]\n",
    "    y_train = y_train[mask]\n",
    "    mask = list(range(num_test))\n",
    "    X_test = X_test[mask]\n",
    "    y_test = y_test[mask]\n",
    "    mask = np.random.choice(num_training, num_dev, replace=False)\n",
    "    X_dev = X_train[mask]\n",
    "    y_dev = y_train[mask]\n",
    "    \n",
    "    # Preprocessing: reshape the image data into rows\n",
    "    X_train = np.reshape(X_train, (X_train.shape[0], -1))\n",
    "    X_val = np.reshape(X_val, (X_val.shape[0], -1))\n",
    "    X_test = np.reshape(X_test, (X_test.shape[0], -1))\n",
    "    X_dev = np.reshape(X_dev, (X_dev.shape[0], -1))\n",
    "    \n",
    "    # Normalize the data: subtract the mean image\n",
    "    mean_image = np.mean(X_train, axis = 0)\n",
    "    X_train -= mean_image\n",
    "    X_val -= mean_image\n",
    "    X_test -= mean_image\n",
    "    X_dev -= mean_image\n",
    "    \n",
    "    # add bias dimension and transform into columns\n",
    "    X_train = np.hstack([X_train, np.ones((X_train.shape[0], 1))])\n",
    "    X_val = np.hstack([X_val, np.ones((X_val.shape[0], 1))])\n",
    "    X_test = np.hstack([X_test, np.ones((X_test.shape[0], 1))])\n",
    "    X_dev = np.hstack([X_dev, np.ones((X_dev.shape[0], 1))])\n",
    "    \n",
    "    return X_train, y_train, X_val, y_val, X_test, y_test, X_dev, y_dev\n",
    "\n",
    "\n",
    "# Invoke the above function to get our data.\n",
    "X_train, y_train, X_val, y_val, X_test, y_test, X_dev, y_dev = get_CIFAR10_data()\n",
    "print('Train data shape: ', X_train.shape)\n",
    "print('Train labels shape: ', y_train.shape)\n",
    "print('Validation data shape: ', X_val.shape)\n",
    "print('Validation labels shape: ', y_val.shape)\n",
    "print('Test data shape: ', X_test.shape)\n",
    "print('Test labels shape: ', y_test.shape)\n",
    "print('dev data shape: ', X_dev.shape)\n",
    "print('dev labels shape: ', y_dev.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Softmax Classifier\n",
    "\n",
    "Your code for this section will all be written inside **cs231n/classifiers/softmax.py**. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss: 2.348806\n",
      "sanity check: 2.302585\n"
     ]
    }
   ],
   "source": [
    "# First implement the naive softmax loss function with nested loops.\n",
    "# Open the file cs231n/classifiers/softmax.py and implement the\n",
    "# softmax_loss_naive function.\n",
    "\n",
    "from cs231n.classifiers.softmax import softmax_loss_naive\n",
    "import time\n",
    "\n",
    "# Generate a random softmax weight matrix and use it to compute the loss.\n",
    "W = np.random.randn(3073, 10) * 0.0001\n",
    "loss, grad = softmax_loss_naive(W, X_dev, y_dev, 0.0)\n",
    "\n",
    "# As a rough sanity check, our loss should be something close to -log(0.1).\n",
    "print('loss: %f' % loss)\n",
    "print('sanity check: %f' % (-np.log(0.1)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-inline"
    ]
   },
   "source": [
    "**Inline Question 1**\n",
    "\n",
    "Why do we expect our loss to be close to -log(0.1)? Explain briefly.**\n",
    "\n",
    "$\\color{blue}{\\textit Your Answer:}$ *Fill this in* 那就是概率为1啊\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "numerical: -0.795505 analytic: -0.795505, relative error: 8.716100e-08\n",
      "numerical: -1.216715 analytic: -1.216715, relative error: 4.247780e-08\n",
      "numerical: -0.704505 analytic: -0.704505, relative error: 8.100074e-08\n",
      "numerical: 1.185990 analytic: 1.185990, relative error: 6.894162e-08\n",
      "numerical: -3.641487 analytic: -3.641487, relative error: 8.209849e-09\n",
      "numerical: 2.776121 analytic: 2.776121, relative error: 9.739357e-09\n",
      "numerical: -0.180144 analytic: -0.180144, relative error: 1.885138e-07\n",
      "numerical: 2.072411 analytic: 2.072411, relative error: 3.222045e-09\n",
      "numerical: 0.499374 analytic: 0.499374, relative error: 4.101382e-08\n",
      "numerical: -2.824792 analytic: -2.824792, relative error: 1.319677e-09\n",
      "numerical: -0.037977 analytic: -0.037977, relative error: 2.719626e-07\n",
      "numerical: 0.809978 analytic: 0.809978, relative error: 8.717583e-08\n",
      "numerical: -1.183025 analytic: -1.183025, relative error: 2.101557e-09\n",
      "numerical: 2.425309 analytic: 2.425309, relative error: 3.124873e-08\n",
      "numerical: -0.415872 analytic: -0.415872, relative error: 1.552535e-07\n",
      "numerical: -1.559080 analytic: -1.559080, relative error: 1.320867e-08\n",
      "numerical: 5.935364 analytic: 5.935364, relative error: 1.536824e-08\n",
      "numerical: 0.301379 analytic: 0.301379, relative error: 1.447583e-07\n",
      "numerical: -0.080286 analytic: -0.080286, relative error: 6.365162e-07\n",
      "numerical: -0.129899 analytic: -0.129899, relative error: 2.703131e-08\n"
     ]
    }
   ],
   "source": [
    "# Complete the implementation of softmax_loss_naive and implement a (naive)\n",
    "# version of the gradient that uses nested loops.\n",
    "loss, grad = softmax_loss_naive(W, X_dev, y_dev, 0.0)\n",
    "\n",
    "# As we did for the SVM, use numeric gradient checking as a debugging tool.\n",
    "# The numeric gradient should be close to the analytic gradient.\n",
    "from cs231n.gradient_check import grad_check_sparse\n",
    "f = lambda w: softmax_loss_naive(w, X_dev, y_dev, 0.0)[0]\n",
    "grad_numerical = grad_check_sparse(f, W, grad, 10)\n",
    "\n",
    "# similar to SVM case, do another gradient check with regularization\n",
    "loss, grad = softmax_loss_naive(W, X_dev, y_dev, 5e1)\n",
    "f = lambda w: softmax_loss_naive(w, X_dev, y_dev, 5e1)[0]\n",
    "grad_numerical = grad_check_sparse(f, W, grad, 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "naive loss: 2.348806e+00 computed in 0.134502s\n",
      "vectorized loss: 2.348806e+00 computed in 0.003483s\n",
      "Loss difference: 0.000000\n",
      "Gradient difference: 0.000000\n"
     ]
    }
   ],
   "source": [
    "# Now that we have a naive implementation of the softmax loss function and its gradient,\n",
    "# implement a vectorized version in softmax_loss_vectorized.\n",
    "# The two versions should compute the same results, but the vectorized version should be\n",
    "# much faster.\n",
    "tic = time.time()\n",
    "loss_naive, grad_naive = softmax_loss_naive(W, X_dev, y_dev, 0.000005)\n",
    "toc = time.time()\n",
    "print('naive loss: %e computed in %fs' % (loss_naive, toc - tic))\n",
    "\n",
    "from cs231n.classifiers.softmax import softmax_loss_vectorized\n",
    "tic = time.time()\n",
    "loss_vectorized, grad_vectorized = softmax_loss_vectorized(W, X_dev, y_dev, 0.000005)\n",
    "toc = time.time()\n",
    "print('vectorized loss: %e computed in %fs' % (loss_vectorized, toc - tic))\n",
    "\n",
    "# As we did for the SVM, we use the Frobenius norm to compare the two versions\n",
    "# of the gradient.\n",
    "grad_difference = np.linalg.norm(grad_naive - grad_vectorized, ord='fro')\n",
    "print('Loss difference: %f' % np.abs(loss_naive - loss_vectorized))\n",
    "print('Gradient difference: %f' % grad_difference)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "tags": [
     "code"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lr 1.000000e-07 reg 2.500000e+04 train accuracy: 0.349612 val accuracy: 0.368000\n",
      "lr 1.000000e-07 reg 5.000000e+04 train accuracy: 0.330469 val accuracy: 0.351000\n",
      "lr 5.000000e-07 reg 2.500000e+04 train accuracy: 0.348469 val accuracy: 0.351000\n",
      "lr 5.000000e-07 reg 5.000000e+04 train accuracy: 0.326000 val accuracy: 0.324000\n",
      "best validation accuracy achieved during cross-validation: 0.368000\n"
     ]
    }
   ],
   "source": [
    "# Use the validation set to tune hyperparameters (regularization strength and\n",
    "# learning rate). You should experiment with different ranges for the learning\n",
    "# rates and regularization strengths; if you are careful you should be able to\n",
    "# get a classification accuracy of over 0.35 on the validation set.\n",
    "from cs231n.classifiers import Softmax\n",
    "results = {}\n",
    "best_val = -1\n",
    "best_softmax = None\n",
    "learning_rates = [1e-7, 5e-7]\n",
    "regularization_strengths = [2.5e4, 5e4]\n",
    "\n",
    "################################################################################\n",
    "# TODO:                                                                        #\n",
    "# Use the validation set to set the learning rate and regularization strength. #\n",
    "# This should be identical to the validation that you did for the SVM; save    #\n",
    "# the best trained softmax classifer in best_softmax.                          #\n",
    "################################################################################\n",
    "# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
    "\n",
    "softmax = Softmax()\n",
    "\n",
    "for lr in learning_rates:\n",
    "    for reg in regularization_strengths:\n",
    "        loss_hist = softmax.train(X_train, y_train, learning_rate=lr, reg=reg, num_iters=1500)\n",
    "        \n",
    "        y_train_pred = softmax.predict(X_train)\n",
    "        acc_train = np.mean(y_train == y_train_pred)\n",
    "        \n",
    "        y_val_pred = softmax.predict(X_val)\n",
    "        acc_val = np.mean(y_val == y_val_pred)\n",
    "        \n",
    "        results[(lr, reg)] = (acc_train, acc_val)\n",
    "        \n",
    "        if acc_val > best_val:\n",
    "            best_val = acc_val\n",
    "            best_softmax = softmax\n",
    "\n",
    "# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
    "    \n",
    "# Print out results.\n",
    "for lr, reg in sorted(results):\n",
    "    train_accuracy, val_accuracy = results[(lr, reg)]\n",
    "    print('lr %e reg %e train accuracy: %f val accuracy: %f' % (\n",
    "                lr, reg, train_accuracy, val_accuracy))\n",
    "    \n",
    "print('best validation accuracy achieved during cross-validation: %f' % best_val)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "softmax on raw pixels final test set accuracy: 0.319000\n"
     ]
    }
   ],
   "source": [
    "# evaluate on test set\n",
    "# Evaluate the best softmax on test set\n",
    "y_test_pred = best_softmax.predict(X_test)\n",
    "test_accuracy = np.mean(y_test == y_test_pred)\n",
    "print('softmax on raw pixels final test set accuracy: %f' % (test_accuracy, ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": [
     "pdf-inline"
    ]
   },
   "source": [
    "**Inline Question 2** - *True or False*\n",
    "\n",
    "Suppose the overall training loss is defined as the sum of the per-datapoint loss over all training examples. It is possible to add a new datapoint to a training set that would leave the SVM loss unchanged, but this is not the case with the Softmax classifier loss.\n",
    "\n",
    "$\\color{blue}{\\textit Your Answer:}$ True\n",
    "\n",
    "\n",
    "$\\color{blue}{\\textit Your Explanation:}$In the SVM if the new data point has a score that is out of the margin range from the correct class score the loss wouldn't change but in the Softmax loss if the score of the new added datapoint be close to +infinity it will adversely affect the loss, but definitely the loss of Softmax will change.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 10 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Visualize the learned weights for each class\n",
    "w = best_softmax.W[:-1,:] # strip out the bias\n",
    "w = w.reshape(32, 32, 3, 10)\n",
    "\n",
    "w_min, w_max = np.min(w), np.max(w)\n",
    "\n",
    "classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']\n",
    "for i in range(10):\n",
    "    plt.subplot(2, 5, i + 1)\n",
    "    \n",
    "    # Rescale the weights to be between 0 and 255\n",
    "    wimg = 255.0 * (w[:, :, :, i].squeeze() - w_min) / (w_max - w_min)\n",
    "    plt.imshow(wimg.astype('uint8'))\n",
    "    plt.axis('off')\n",
    "    plt.title(classes[i])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
